package com.agricultural.machine.common;

import com.agricultural.machine.environment.EnvironmentData;
import com.agricultural.machine.environment.EnvironmentMonitor;
import com.agricultural.machine.environment.EnvironmentObserver;
import com.agricultural.machine.messaging.Message;
import com.agricultural.machine.messaging.MessageBroker;
import com.agricultural.machine.path.PathOptimizer;
import com.agricultural.machine.state.IdleState;
import com.agricultural.machine.state.WorkingState;

import java.util.UUID;

/**
 * 抽象农机类
 */
public abstract class AbstractMachine implements IMachine, EnvironmentObserver {
    private final String machineId;
    private final String type;
    private MachineState state;
    private double currentX;
    private double currentY;
    private boolean emergencyStopped;
    protected PathOptimizer pathOptimizer;
    private boolean autoOperationEnabled;
    
    public AbstractMachine(String type) {
        this.machineId = UUID.randomUUID().toString().substring(0, 8);
        this.type = type;
        this.state = new IdleState();
        this.currentX = 0.0;
        this.currentY = 0.0;
        this.emergencyStopped = false;
        this.pathOptimizer = PathOptimizer.getInstance();
        this.autoOperationEnabled = false;
        
        // 注册为环境观察者
        EnvironmentMonitor.getInstance().addObserver(this);
    }
    
    @Override
    public String getMachineId() {
        return machineId;
    }
    
    @Override
    public String getType() {
        return type;
    }
    
    @Override
    public void start() {
        if (!emergencyStopped) {
            state.start(this);
        } else {
            System.out.println("农机 " + machineId + " 处于紧急停止状态，无法启动");
        }
    }
    
    @Override
    public void stop() {
        state.stop(this);
    }
    
    @Override
    public boolean isRunning() {
        return state instanceof WorkingState;
    }
    
    @Override
    public void setState(MachineState state) {
        this.state = state;
    }
    
    @Override
    public MachineState getState() {
        return state;
    }
    
    @Override
    public void executeTask(String task) {
        if (emergencyStopped) {
            System.out.println("农机 " + machineId + " 处于紧急停止状态，无法执行任务");
            return;
        }
        
        state.executeTask(this, task);
    }
    
    @Override
    public void setEmergencyStop(boolean emergency) {
        this.emergencyStopped = emergency;
        if (emergency) {
            System.out.println("农机 " + machineId + " 紧急停止已激活");
            if (isRunning()) {
                stop();
            }
        } else {
            System.out.println("农机 " + machineId + " 紧急停止已解除");
        }
    }
    
    @Override
    public boolean isEmergencyStopped() {
        return emergencyStopped;
    }
    
    @Override
    public void updatePosition(double x, double y) {
        this.currentX = x;
        this.currentY = y;
    }
    
    @Override
    public double getCurrentX() {
        return currentX;
    }
    
    @Override
    public double getCurrentY() {
        return currentY;
    }
    
    @Override
    public String getPosition() {
        return String.format("(%.2f, %.2f)", currentX, currentY);
    }
    
    /**
     * 启用自动操作模式
     */
    public void enableAutoOperation() {
        this.autoOperationEnabled = true;
        System.out.println("农机 " + machineId + " 已启用自动操作模式");
    }
    
    /**
     * 禁用自动操作模式
     */
    public void disableAutoOperation() {
        this.autoOperationEnabled = false;
        System.out.println("农机 " + machineId + " 已禁用自动操作模式");
    }
    
    /**
     * 判断是否启用自动操作模式
     */
    public boolean isAutoOperationEnabled() {
        return autoOperationEnabled;
    }
    
    /**
     * 处理环境变化 - 实现观察者接口方法
     */
    @Override
    public void onEnvironmentChanged(EnvironmentData environmentData) {
        if (!autoOperationEnabled) {
            return; // 如果未启用自动操作，则不响应环境变化
        }
        
        System.out.println("\n农机 " + machineId + " (" + type + ") 正在响应环境变化...");
        
        // 记录当前策略
        String oldStrategy = pathOptimizer.getCurrentPathStrategy().getName();
        
        // 检测到障碍物时，发送消息并调整路径
        if (environmentData.isObstacleDetected() && isRunning()) {
            System.out.println("【障碍物检测】农机 " + machineId + " 检测到障碍物: " + environmentData.getObstacleType());
            
            // 向其他农机广播障碍物信息
            broadcastObstacleInfo(environmentData.getObstacleType());
            
            // 自动更新路径策略
            String bestStrategy = environmentData.determineBestPathStrategy();
            pathOptimizer.setPathStrategy(bestStrategy);
            
            if (!oldStrategy.equals(bestStrategy)) {
                System.out.println("【策略自动切换】农机 " + machineId + " 因检测到障碍物，已从 [" + 
                        oldStrategy + "] 自动切换至 [" + bestStrategy + "] 策略");
            }
        } 
        // 检查土壤湿度变化
        else if (isRunning()) {
            double soilMoisture = environmentData.getSoilMoisture();
            String bestStrategy = environmentData.determineBestPathStrategy();
            
            if (soilMoisture > 65 && "terrainOptimized".equals(bestStrategy) && !oldStrategy.equals(bestStrategy)) {
                pathOptimizer.setPathStrategy(bestStrategy);
                System.out.println("【策略自动切换】农机 " + machineId + " 因检测到土壤湿度过高 (" + 
                        String.format("%.1f", soilMoisture) + "%)，已从 [" + 
                        oldStrategy + "] 自动切换至 [" + bestStrategy + "] 策略");
            } 
            else if (soilMoisture <= 65 && "direct".equals(bestStrategy) && !oldStrategy.equals(bestStrategy)) {
                pathOptimizer.setPathStrategy(bestStrategy);
                System.out.println("【策略自动切换】农机 " + machineId + " 因检测到环境良好，已从 [" + 
                        oldStrategy + "] 自动切换至 [" + bestStrategy + "] 策略");
            }
        }
        
        // 根据农机类型和环境数据自动调整操作
        automaticAdjustOperation(environmentData);
    }
    
    /**
     * 根据环境数据自动调整操作 - 子类根据自身特点实现
     */
    protected abstract void automaticAdjustOperation(EnvironmentData environmentData);
    
    /**
     * 向其他农机广播障碍物信息
     */
    private void broadcastObstacleInfo(String obstacleType) {
        Message message = new Message(
                machineId,
                "broadcast",
                "obstacle_detected",
                "检测到障碍物: " + obstacleType + ", 位置: " + getPosition()
        );
        MessageBroker.getInstance().sendMessage(message);
    }
    
    /**
     * 接收来自其他农机的消息
     */
    public void receiveMessage(Message message) {
        if (!autoOperationEnabled) {
            return;
        }
        
        System.out.println("农机 " + machineId + " 收到消息: [" + message.getType() + "] " + message.getContent());
        
        // 处理不同类型的消息
        if ("obstacle_detected".equals(message.getType()) && isRunning()) {
            // 收到障碍物警告，切换到避障策略
            pathOptimizer.setPathStrategy("avoidObstacle");
            System.out.println("农机 " + machineId + " 响应障碍物警告，切换至避障策略");
        }
    }
}









